"""
工作空间管理工具函数
用于备份、恢复和管理工作空间配置
"""

import os
import json
import uuid
import frappe
import shutil
from datetime import datetime


def backup_workspace(workspace_name="Home"):
    """
    备份指定工作空间的配置
    
    Args:
        workspace_name (str): 工作空间名称，默认为"Home"
    
    Returns:
        str: 备份文件路径，失败返回None
    """
    try:
        # 创建备份目录
        backup_dir = frappe.get_app_path("theme", "backups")
        if not os.path.exists(backup_dir):
            os.makedirs(backup_dir)
        
        # 获取工作空间文档
        workspace_doc = frappe.get_doc("Workspace", workspace_name)
        
        # 创建备份文件名（包含时间戳）
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_filename = f"{workspace_name.lower()}_workspace_backup_{timestamp}.json"
        backup_path = os.path.join(backup_dir, backup_filename)
        
        # 准备备份数据，处理custom_blocks的序列化
        custom_blocks_data = []
        for block in workspace_doc.get("custom_blocks", []):
            if hasattr(block, 'as_dict'):
                # 如果是Frappe文档对象，转换为字典
                custom_blocks_data.append(block.as_dict())
            elif isinstance(block, dict):
                # 如果已经是字典，直接使用
                custom_blocks_data.append(block)
            else:
                # 其他情况，尝试转换为字典
                try:
                    custom_blocks_data.append({
                        "custom_block_name": getattr(block, 'custom_block_name', ''),
                        "label": getattr(block, 'label', '')
                    })
                except:
                    # 如果转换失败，跳过该项
                    continue
        
        backup_data = {
            "name": workspace_doc.name,
            "content": workspace_doc.content,
            "custom_blocks": custom_blocks_data,
            "backup_time": timestamp,
            "backup_by": "theme_install"
        }
        
        # 写入备份文件，使用自定义JSON编码器处理datetime等对象
        with open(backup_path, 'w', encoding='utf-8') as f:
            json.dump(backup_data, f, indent=2, ensure_ascii=False, default=str)
        
        print(f"✅ 成功备份 {workspace_name} 工作空间到: {backup_path}")
        return backup_path
        
    except Exception as e:
        frappe.log_error(f"备份 {workspace_name} 工作空间时出错: {str(e)}")
        print(f"❌ 备份 {workspace_name} 工作空间失败: {str(e)}")
        return None


def restore_workspace_from_backup(workspace_name="Home", backup_path=None):
    """
    从备份文件恢复工作空间配置
    
    Args:
        workspace_name (str): 工作空间名称，默认为"Home"
        backup_path (str): 备份文件路径，如果为None则使用最新的备份文件
    
    Returns:
        bool: 恢复成功返回True，失败返回False
    """
    try:
        # 如果没有指定备份路径，查找最新的备份文件
        if backup_path is None:
            backup_dir = frappe.get_app_path("theme", "backups")
            if not os.path.exists(backup_dir):
                print(f"❌ 备份目录不存在: {backup_dir}")
                return False
            
            # 查找最新的备份文件
            backup_files = [f for f in os.listdir(backup_dir) 
                          if f.startswith(f"{workspace_name.lower()}_workspace_backup_") 
                          and f.endswith(".json")]
            
            if not backup_files:
                print(f"❌ 未找到 {workspace_name} 工作空间的备份文件")
                return False
            
            # 按时间戳排序，获取最新的备份文件
            backup_files.sort(reverse=True)
            backup_path = os.path.join(backup_dir, backup_files[0])
        
        # 检查备份文件是否存在
        if not os.path.exists(backup_path):
            print(f"❌ 备份文件不存在: {backup_path}")
            return False
        
        # 读取备份数据
        with open(backup_path, 'r', encoding='utf-8') as f:
            backup_data = json.load(f)
        
        # 获取工作空间文档
        workspace_doc = frappe.get_doc("Workspace", workspace_name)
        
        # 恢复配置
        workspace_doc.content = backup_data.get("content", "[]")
        workspace_doc.custom_blocks = []
        
        # 恢复custom_blocks
        for block_data in backup_data.get("custom_blocks", []):
            # 确保只添加必要的字段
            clean_block_data = {
                "custom_block_name": block_data.get("custom_block_name", ""),
                "label": block_data.get("label", "")
            }
            workspace_doc.append("custom_blocks", clean_block_data)
        
        # 保存更改
        workspace_doc.save(ignore_permissions=True)
        frappe.db.commit()
        
        print(f"✅ 成功从备份恢复 {workspace_name} 工作空间: {backup_path}")
        return True
        
    except Exception as e:
        frappe.log_error(f"恢复 {workspace_name} 工作空间时出错: {str(e)}")
        print(f"❌ 恢复 {workspace_name} 工作空间失败: {str(e)}")
        return False


def add_custom_block_to_workspace(workspace_name="Home", block_name="home", position="top"):
    """
    向工作空间添加自定义HTML块
    
    Args:
        workspace_name (str): 工作空间名称，默认为"Home"
        block_name (str): 自定义HTML块名称，默认为"home"
        position (str): 插入位置，"top"为顶部，"bottom"为底部，默认为"top"
    
    Returns:
        bool: 添加成功返回True，失败返回False
    """
    try:
        # 检查Custom HTML Block是否存在
        if not frappe.db.exists("Custom HTML Block", block_name):
            print(f"❌ Custom HTML Block '{block_name}' 不存在")
            return False
        
        # 获取工作空间文档
        workspace_doc = frappe.get_doc("Workspace", workspace_name)
        content = json.loads(workspace_doc.content or "[]")
        
        # 检查是否已经存在该自定义块
        for item in content:
            if (item.get("type") == "custom_block" and 
                item.get("data", {}).get("custom_block_name") == block_name):
                print(f"📝 Custom Block '{block_name}' 已存在于 {workspace_name} 工作空间")
                return True
        
        # 生成随机ID
        random_id = str(uuid.uuid4())[:10]
        
        # 创建Custom Block配置
        new_custom_block = {
            "id": random_id,
            "type": "custom_block",
            "data": {
                "custom_block_name": block_name,
                "col": 12
            }
        }
        
        # 根据位置插入
        if position == "top":
            content.insert(0, new_custom_block)
        else:
            content.append(new_custom_block)
        
        # 更新custom_blocks字段
        if not hasattr(workspace_doc, 'custom_blocks') or not workspace_doc.custom_blocks:
            workspace_doc.custom_blocks = []
        
        # 检查并添加到custom_blocks列表
        exists = False
        for cb in workspace_doc.custom_blocks:
            if cb.get("custom_block_name") == block_name:
                exists = True
                break
        
        if not exists:
            workspace_doc.append("custom_blocks", {
                "custom_block_name": block_name,
                "label": block_name
            })
        
        # 保存更改
        workspace_doc.content = json.dumps(content)
        workspace_doc.save(ignore_permissions=True)
        frappe.db.commit()
        
        print(f"✅ 成功添加 Custom Block '{block_name}' 到 {workspace_name} 工作空间，ID: {random_id}")
        return True
        
    except Exception as e:
        frappe.log_error(f"添加 Custom Block 到 {workspace_name} 工作空间时出错: {str(e)}")
        print(f"❌ 添加 Custom Block 失败: {str(e)}")
        return False


def clean_workspace_elements(workspace_name="Home", keep_types=None):
    """
    清理工作空间中的元素，只保留指定类型的元素
    
    Args:
        workspace_name (str): 工作空间名称，默认为"Home"
        keep_types (list): 要保留的元素类型列表，如["html", "custom_block"]
    
    Returns:
        bool: 清理成功返回True，失败返回False
    """
    try:
        if keep_types is None:
            keep_types = ["html", "custom_block"]
        
        # 获取工作空间文档
        workspace_doc = frappe.get_doc("Workspace", workspace_name)
        content = json.loads(workspace_doc.content or "[]")
        
        # 统计删除前的元素
        original_count = len(content)
        type_counts = {}
        for item in content:
            item_type = item.get("type", "unknown")
            type_counts[item_type] = type_counts.get(item_type, 0) + 1
        
        # 过滤元素，只保留指定类型
        filtered_content = [item for item in content if item.get("type") in keep_types]
        
        # 统计删除后的元素
        filtered_count = len(filtered_content)
        deleted_count = original_count - filtered_count
        
        # 更新工作空间内容
        workspace_doc.content = json.dumps(filtered_content)
        workspace_doc.save(ignore_permissions=True)
        frappe.db.commit()
        
        print(f"✅ 成功清理 {workspace_name} 工作空间:")
        print(f"   - 原始元素数量: {original_count}")
        print(f"   - 删除元素数量: {deleted_count}")
        print(f"   - 保留元素数量: {filtered_count}")
        print(f"   - 保留类型: {', '.join(keep_types)}")
        
        # 显示删除的元素类型统计
        if deleted_count > 0:
            deleted_types = {k: v for k, v in type_counts.items() if k not in keep_types}
            if deleted_types:
                print(f"   - 删除的元素类型: {deleted_types}")
        
        return True
        
    except Exception as e:
        frappe.log_error(f"清理 {workspace_name} 工作空间时出错: {str(e)}")
        print(f"❌ 清理 {workspace_name} 工作空间失败: {str(e)}")
        return False


def get_workspace_backup_path(workspace_name="Home"):
    """
    获取最新的工作空间备份文件路径
    
    Args:
        workspace_name (str): 工作空间名称，默认为"Home"
    
    Returns:
        str: 备份文件路径，未找到返回None
    """
    try:
        backup_dir = frappe.get_app_path("theme", "backups")
        if not os.path.exists(backup_dir):
            return None
        
        # 查找最新的备份文件
        backup_files = [f for f in os.listdir(backup_dir) 
                      if f.startswith(f"{workspace_name.lower()}_workspace_backup_") 
                      and f.endswith(".json")]
        
        if not backup_files:
            return None
        
        # 按时间戳排序，获取最新的备份文件
        backup_files.sort(reverse=True)
        return os.path.join(backup_dir, backup_files[0])
        
    except Exception as e:
        frappe.log_error(f"获取 {workspace_name} 工作空间备份路径时出错: {str(e)}")
        return None